package util;

import mutation.*;
import crossover.*;
import selection.*;
import immigration.*;
import initialization.PopulationInitializer;
public class GAOperationsConfig {

	private static Crossover crossoverStrategy = null;
	public static Crossover getCrossoverStrategy() {

		if (GAOperationsConfig.crossoverStrategy != null)
			return GAOperationsConfig.crossoverStrategy;

		String strategy = "crossover.SingleCrossOver";

		try {
			GAOperationsConfig.crossoverStrategy = (Crossover) Class.forName(
					strategy).newInstance();
			return GAOperationsConfig.crossoverStrategy;
		} catch (Exception ex) {
			throw new RuntimeException(
					"CrossoverStrategy could not be determined, verify the configuration file",
					ex);
		}
	}
	private static Mutation mutationChangeValueStrategy = null;
	public static Mutation getMutationChangeValueStrategy() {

		if (GAOperationsConfig.mutationChangeValueStrategy != null)
			return GAOperationsConfig.mutationChangeValueStrategy;

		String strategy = "mutation.RandomChangeInputValue";
		if(GAConfig.UseReadWrietRelation)
			strategy = "mutation.MDRChangeInputValue";
		try {
			GAOperationsConfig.mutationChangeValueStrategy = (Mutation) Class.forName(
					strategy).newInstance();
			return GAOperationsConfig.mutationChangeValueStrategy;
		} catch (Exception ex) {
			throw new RuntimeException(
					"mutation Change Value Strategy could not be determined, the  file is not exisit "+ strategy,
					ex);
		}
	}
	private static Mutation mutationMuthodInsertStrategy = null;
	public static Mutation getMutationMethodInsertStrategy() {
		if (GAOperationsConfig.mutationMuthodInsertStrategy != null)
			return GAOperationsConfig.mutationMuthodInsertStrategy;

		String strategy = "mutation.RandomInsertMethodCall";
		if(GAConfig.UseReadWrietRelation)
			strategy = "mutation.MDRInsertMethodCall";

		try {
			GAOperationsConfig.mutationMuthodInsertStrategy = (Mutation) Class.forName(
					strategy).newInstance();
			return GAOperationsConfig.mutationMuthodInsertStrategy;
		} catch (Exception ex) {
			throw new RuntimeException(
					"mutation Muthod Insert Strategy could not be determined, verify the configuration file",
					ex);
		}
	}
	private static Mutation mutationMuthodDeleteStrategy = null;
	public static Mutation getMutationMethodDeleteStrategy() {
		if (GAOperationsConfig.mutationMuthodDeleteStrategy != null)
			return GAOperationsConfig.mutationMuthodDeleteStrategy;

		String strategy = "mutation.RandomDeleteMethodCall";
		if(GAConfig.UseReadWrietRelation)
			strategy = "mutation.MDRDeleteMethodCall";

		try {
			GAOperationsConfig.mutationMuthodDeleteStrategy = (Mutation) Class.forName(
					strategy).newInstance();
			return GAOperationsConfig.mutationMuthodDeleteStrategy;
		} catch (Exception ex) {
			throw new RuntimeException(
					"mutation Muthod Delete Strategy could not be determined, verify the configuration file",
					ex);
		}
	}
	
	  private static PopulationInitializer populationInitializer = null;
	  	public static PopulationInitializer getPopulationInitializer() {
		if (GAOperationsConfig.populationInitializer != null)
			return GAOperationsConfig.populationInitializer;

		String strategy = "initialization.RandomPopulationInitializer";
		if(!GAConfig.randomInitialPopulation)
			 strategy = "initialization.MethodDependencePopulationInitializer";
		try {
			GAOperationsConfig.populationInitializer = (PopulationInitializer) Class.forName(
					strategy).newInstance();
			return GAOperationsConfig.populationInitializer;
		} catch (Exception ex) {
			throw new RuntimeException(
					"PopulationInitializer Strategy could not be determined, verify the configuration file",
					ex);
		}
	}
	
		
	private static Selection    parentSelector       = null;
	public static Selection getParentSelector() {
		try {
			if (GAOperationsConfig.parentSelector != null)
				return GAOperationsConfig.parentSelector;

		String selector = "selection.TournamentSelection";
			
			GAOperationsConfig.parentSelector = (Selection) Class.forName(
					selector).newInstance();
			return GAOperationsConfig.parentSelector;
		} catch (Exception ex) {
			throw new RuntimeException(
					"ParentSelector could not be determined, verify the configuration file",
					ex);
		}

	}
	private static Immigration immigrationStrategy = null;
	public static Immigration getImmigrationStrategy() {
		if (GAOperationsConfig.immigrationStrategy != null)
			return GAOperationsConfig.immigrationStrategy;
		String immigration="immigration.RandomBasedImmigration";
	//	if(GAConfig.Use_Elitism_based_Immigrants)
			immigration = "immigration.ElitismBasedImmigration";

		try {
			GAOperationsConfig.immigrationStrategy = (Immigration) Class.forName(immigration).newInstance();
		} catch (Exception ex) {
			System.err.println("GAOperationsConfig.getImmigrationStrategy() Immigration Strategy could not be determined, verify the configuration file");
			System.exit(1);

		}
		return GAOperationsConfig.immigrationStrategy;

	}

}
